﻿#include "qqmusic.h"
#include "ui_qqmusic.h"

#include "commonpage.h"
#include "musiclist.h"
#include "music.h"

#include <QFileDialog>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QDebug>
#include <QPushButton>
#include <QSqlDatabase>
#include <QMessageBox>
#include <QSqlQuery>
#include <QSystemTrayIcon>
#include <QMenu>

QQMusic::QQMusic(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::QQMusic)
    , currentIndex(-1)
{
    ui->setupUi(this);

    initUi();

    // 数据库模块初始化
    initSqlite();

    // 音乐播放控制
    initPlayer();

    // 将数据库中的信息,写入MusicList
    initMusicList();

    connectSignalAndSlots();
}

QQMusic::~QQMusic()
{
    delete ui;
}

void QQMusic::initUi()
{
    // 添加最小化托盘
    QSystemTrayIcon* trayIcon = new QSystemTrayIcon(QIcon(":/images/tubiao.png"), this);
    trayIcon->show();
    QMenu* menu = new QMenu(this);
    menu->addAction("显示", this, &QWidget::showNormal);
    menu->addAction("退出", this, &QQMusic::onQuitQQMusic);
    trayIcon->setContextMenu(menu);

    // 不支持最大化
    ui->max->setEnabled(false);

    //设置主界面无边框
    this->setWindowFlag(Qt::FramelessWindowHint);

    this->setWindowIcon(QIcon(":/images/tubiao.png"));

    //设置窗口背景透明
    this->setAttribute(Qt::WA_TranslucentBackground, true);//第二个参数默认true;

    //给窗口设置阴影效果
    QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect(this);
    shadowEffect->setOffset(0, 0);
    shadowEffect->setColor(QColor(0, 0, 0, 80));
    shadowEffect->setBlurRadius(10);// 不支持
    this->setGraphicsEffect(shadowEffect);

    //设置btFrom的图片和文字 (bodyleft区域->onlineMusic部分)
    ui->rec->setIconAndText(QString(":/images/rec.png"), QString("推荐"), 0);
    ui->radio->setIconAndText(QString(":/images/radio.png"), QString("电台"), 1);
    ui->music->setIconAndText(QString(":/images/music.png"), QString("音乐馆"), 2);
    //                     (bodyleft区域->myMusic部分)
    ui->like->setIconAndText(QString(":/images/like.png"), QString("我喜欢"), 3);
    ui->local->setIconAndText(QString(":/images/local.png"), QString(" 本地下载"), 4);
    ui->recent->setIconAndText(QString(":/images/recent.png"), QString("最近播放"), 5);

    // 将本地下载的动画效果展示出来
    ui->stackedWidget->setCurrentIndex(4);// 并且设置默认显示界面
    currentPage = ui->localPage; //设置 当前页面 的默认显示
    ui->local->showAnimation(true);

    // 初始化推荐界面
    srand(time(NULL));// 设置随机数种子,跟随系统时间
    ui->recMusicBox->initRecBoxUi(randomPiction(), 1);
    ui->supplyMusicBox->initRecBoxUi(randomPiction(), 2);

    // 设置我喜欢、本地音乐、最近播放页面
    ui->likePage->setCommonPageUI("我喜欢", ":/images/rec/008.png");
    ui->localPage->setCommonPageUI("本地音乐", ":/images/localbg.png");
    ui->recentPage->setCommonPageUI("最近播放页面", ":/images/rec/003.png");

    // 播放控制区 播放暂停图标的设置
    ui->play->setIcon(QIcon(":/images/play.png"));
    // 播放模式图片的设置
    ui->playMode->setIcon(QIcon(":/images/order_play.png"));

    // 设置点击音量键弹出调节音量窗口
    volumeTool = new VolumeTool(this);

    // 设置歌词页面
    lrcPage = new LrcPage(this);
    lrcPage->setGeometry(10, 10, lrcPage->width(), lrcPage->height());
    lrcPage->hide();

    // 初始化上移动画对象
    lrcPageAnimal = new QPropertyAnimation(lrcPage, "geometry", this);
    lrcPageAnimal->setDuration(500);
    lrcPageAnimal->setStartValue(QRect(10, 10+lrcPage->height(), lrcPage->width(), lrcPage->height()));
    lrcPageAnimal->setEndValue(QRect(10, 10, lrcPage->width(), lrcPage->height()));
}

void QQMusic::initSqlite()
{
    // 1.创建数据库连接(进行数据库驱动加载)
    sqlite = QSqlDatabase::addDatabase("QSQLITE");

    // 2.设置数据库名称
    sqlite.setDatabaseName("qqMusic.db");

    // 3.打开数据库
    if(!sqlite.open())
    {
        QMessageBox::critical(this, "QQMusic", "数据库打开失败!");
        return;
    }

    //    QString musicId;
    //    QString musicName;
    //    QString singerName;
    //    QString albumName;
    //    QUrl musicUrl;
    //    qint64 duration;
    //    bool isLike;
    //    bool isHistory;
    // 4.创建数据库表
    QString sql = "CREATE TABLE IF NOT EXISTS MusicInfo(\
                            id INTEGER PRIMARY KEY AUTOINCREMENT,\
                            musicId VARCHAR(50) UNIQUE,\
                            musicName VARCHAR(50),\
                            singerName VARCHAR(50),\
                            albumName VARCHAR(50),\
                            musicUrl VARCHAR(256),\
                            duration BIGINT,\
                            isLike INTEGER,\
                            isHistory INTEGER\
                            )";
    QSqlQuery query;
    if(!query.exec(sql))
    {
        QMessageBox::critical(this, "QQMusic", "初始化错误, 创建数据库表失败!");
        return;
    }

    qDebug() << "创建[MusicInfo]表成功!";
}

void QQMusic::initMusicList()
{
    // 将数据库中的信息导入musicList中后
    // 需要将音乐通过具体页面类型以及属性显示到页面上
    musicList.readFromDB();

    ui->likePage->setMusicListType(PageType::LIKE_PAGE);
    ui->likePage->reFresh(musicList);
    ui->localPage->setMusicListType(PageType::LOCAL_PAGE);
    ui->localPage->reFresh(musicList);
    ui->recentPage->setMusicListType(PageType::HISTORY_PAGR);
    ui->recentPage->reFresh(musicList);
}

void QQMusic::connectSignalAndSlots()
{
    // 关联btFrom的信号和处理该信号的槽函数
    connect(ui->rec, &BtForm::btClick, this, &QQMusic::onBtFromClick);
    connect(ui->radio, &BtForm::btClick, this, &QQMusic::onBtFromClick);
    connect(ui->music, &BtForm::btClick, this, &QQMusic::onBtFromClick);
    connect(ui->like, &BtForm::btClick, this, &QQMusic::onBtFromClick);
    connect(ui->local, &BtForm::btClick, this, &QQMusic::onBtFromClick);
    connect(ui->recent, &BtForm::btClick, this, &QQMusic::onBtFromClick);

    // 分别将 CommonPage::updataLikeMusic信号 和  QQMusic::updataLikeMusicAndPage-->处理该信号的槽函数 关联
    connect(ui->likePage, &CommonPage::updateLikeMusic, this, &QQMusic::updateLikeMusicAndPage);
    connect(ui->localPage, &CommonPage::updateLikeMusic, this, &QQMusic::updateLikeMusicAndPage);
    connect(ui->recentPage, &CommonPage::updateLikeMusic, this, &QQMusic::updateLikeMusicAndPage);


    // 播放控制区的信号和槽函数关联
    // 播放暂停按钮
    connect(ui->play, &QPushButton::clicked, this, &QQMusic::onPlayClicked);
    // 上一首
    connect(ui->playUp, &QPushButton::clicked, this, &QQMusic::onPlayUpClicked);
    // 下一首
    connect(ui->playDown, &QPushButton::clicked, this, &QQMusic::onPlayDownClicked);
    // 点击playMode按钮切换模式,触发点击信号,该槽函数处理
    connect(ui->playMode, &QPushButton::clicked, this, &QQMusic::onPlaybackModeCliked);


    // 对于 likepage localpage recentpage 都有 播放所有的按钮
    connect(ui->likePage, &CommonPage::playAll, this, &QQMusic::playAll);
    connect(ui->localPage, &CommonPage::playAll, this, &QQMusic::playAll);
    connect(ui->recentPage, &CommonPage::playAll, this, &QQMusic::playAll);

    // 处理likePage、localPage、recentPage中ListItemBox双击
     connect(ui->likePage, &CommonPage::playMusicByIndex, this, &QQMusic::playMusicByIndex);
     connect(ui->localPage, &CommonPage::playMusicByIndex, this, &QQMusic::playMusicByIndex);
     connect(ui->recentPage, &CommonPage::playMusicByIndex, this, &QQMusic::playMusicByIndex);

     // 处理音量 是否静音
     connect(volumeTool, &VolumeTool::setSilence, this, &QQMusic::setPlayerSilence);
     // 设置音量
     connect(volumeTool, &VolumeTool::setMusicVolume, this, &QQMusic::setPlayerVolume);
     // 关联 进度条的拖拽
     connect(ui->progressBar, &MusicSlider::setMusicSliderPosition, this, &QQMusic::onMusicSliderChanged);

     // 关联 显示歌词
     connect(ui->lrcWord, &QPushButton::clicked, this, &QQMusic::onLrcwordClicked);
}

// 设置随机图片【歌曲的图片】
QJsonArray QQMusic::randomPiction()
{
    //模拟 推荐文本 + 推按照片路径
    QVector<QString> vecImageName;
    vecImageName << "001.png" << "003.png" << "004.png" << "005.png" << "006.png" << "007.png" << "008.png"
                 << "009.png" << "010.png" << "011.png" << "012.png" << "013.png" << "014.png" << "015.png"
                 << "016.png" << "017.png" << "018.png" << "019.png" << "020.png" << "021.png" << "022.png"
                 << "023.png" << "024.png" << "025.png" << "026.png" << "027.png" << "028.png" << "029.png"
                 << "030.png" << "031.png" << "032.png" << "033.png" << "034.png" << "035.png" << "036.png"
                 << "037.png" << "038.png" << "039.png" << "040.png";

    //将顺序打散
    std::random_shuffle(vecImageName.begin(), vecImageName. end());

    // 001.png
    // path: ":/images/rec/"+vecImageName[i];
    // text: "推荐-001"
    QJsonArray objArray;
    for(int i = 0; i < vecImageName.size(); ++i)
    {
        QJsonObject obj;
        obj.insert("path", ":/images/rec/" + vecImageName[i]);

        // arg(i, 3, 10, QCchar('0'))
        // i：要放到 %1位置的数据
        // 3: 三位数
        // 10：表示10进制数
        // QChar('0')：数字不够三位，前面由字符'0'填充
        QString strText = QString("推荐-%1").arg(i, 3, 10, QChar('0'));
        obj.insert("text", strText);

        objArray.append(obj);
    }

    return objArray;
}

void QQMusic::initPlayer()
{
    // 1.初始化媒体播放相关的类对象
    player = new QMediaPlayer(this);
    playList = new QMediaPlaylist(this);

    // 2.设置默认播放模式: 循环列表
    playList->setPlaybackMode(QMediaPlaylist::Loop);

    // 3.将媒体列表设置到播放媒体对象中
    player->setPlaylist(playList);

    // 4.设置媒体音量默认大小, 20%
    player->setVolume(20);

    // 点击播放按钮切换状态触发信号,调用槽函数改变图片(分离,各做各的事)
    connect(player, &QMediaPlayer::stateChanged, this, &QQMusic::onPlayerStatusChanged);

    //关联QMediaPlayer::durationChanged信号
    connect(player, &QMediaPlayer::durationChanged, this, &QQMusic::onDurationChanged);

    // 状态切换触发信号,该槽函数处理
    connect(playList, &QMediaPlaylist::playbackModeChanged, this, &QQMusic::onPlaybackModeChanged);

    // 播放歌曲切换,index会发生改变, 触发信号,交给该槽函数处理
    connect(playList, &QMediaPlaylist::currentIndexChanged, this, &QQMusic::onCurrentIndexChanged);

    // 关联 QMediaPlayer::durationChanged(int duration);
    connect(player, &QMediaPlayer::durationChanged, this, &QQMusic::onDurationChanged);

    // 关联 QMediaPlayer::positionChanged(int position);
    connect(player, &QMediaPlayer::positionChanged, this, &QQMusic::onPositionChanged);

    // 播放的数据元改变,从而设置 歌名,歌手等属性
    connect(player, &QMediaPlayer::metaDataAvailableChanged, this, &QQMusic::onMetaDataAvailableChanged);
}

void QQMusic::updateBtfromAnimal()
{
    // 获取currentPage 在stackWidget中的索引
    int index = ui->stackedWidget->indexOf(currentPage);
    if(index == -1)
    {
        qDebug() << "该页面不存在";
        return;
    }

    // 获取所有 btfrom类的子控件
    QList<BtForm*> btfroms = this->findChildren<BtForm*>();
    for(auto btfrom : btfroms)
    {
        if(btfrom->getPageId() == index)
        {
            btfrom->showAnimation(true);
        }
        else
        {
            btfrom->showAnimation(false);
        }
    }
}

void QQMusic::onQuitQQMusic()
{
    // 将歌曲信息写入数据库
    musicList.writeToDB();

    // 断开和sqlite的连接
    sqlite.close();

    //关闭窗口
    this->close();
}

void QQMusic::on_quit_clicked()
{    
    this->hide();
}

void QQMusic::onBtFromClick(int pageId)
{
    //1.获取父类下(当前页面下)的所有 BtForm 按钮类型的对象
    QList<BtForm*> btFormList = this->findChildren<BtForm*>();

    //2.遍历所有对象,如果不是当前id的按钮,则把之前设置的背景颜色清除掉
    for(auto& btForm : btFormList)
    {
        if(btForm->getPageId() != pageId)
        {
            btForm->clearbackGroundColor();
        }
    }

    // 在重叠窗口进行显示,你想显示的某一页
    ui->stackedWidget->setCurrentIndex(pageId);
    qDebug() << pageId;

    isDrag = false; // 再点击btfrom时, 不能移动窗口
}

// 用 button() 判断触发事件的按钮（如点击）。// 用 buttons() 判断当前按住的按钮（如拖动时）
void QQMusic::mouseMoveEvent(QMouseEvent *event)//鼠标的移动
{
    // " == " 确保只有左键被按住（无其他键）
    if(Qt::LeftButton == event->buttons() && isDrag)
    {
        move(event->globalPos() -  dragPosition);
//        move(event->globalPosition().toPoint() - dragPosition);
        return;
    }
    //如果是其他按键,则交给父类去处理
    QWidget::mouseMoveEvent(event);
}

void QQMusic::mousePressEvent(QMouseEvent *event)//鼠标的按压
{
    if(Qt::LeftButton == event->button())
    {
        isDrag = true;

        //geometry().topLeft() --->获取当前控件在父容器坐标系中的左上角位置,返回一个QPoint对象(x, y);
        dragPosition = event->globalPos() - geometry().topLeft();//相对位移
//        dragPosition = event->globalPosition().toPoint() - geometry().topLeft();
        return;
    }
    //如果是其他按键,则交给父类去处理
    QWidget::mousePressEvent(event);
}

void QQMusic::on_volume_clicked()
{
    // 1.将 控件局部坐标 转换为 屏幕全局坐标 QPoint QWidget::mapToGlobal(const QPoint &pos) const;
    //  获取 ui->volume按钮控件的局部坐标(如leftTop坐标), 并转化为基于屏幕的全局坐标
    QPoint volumePointLeftTop = ui->volume->mapToGlobal(QPoint(0, 0));// QPoint(0, 0)就是leftTop坐标

    // 2. 计算volumeTool控件需要移动到的位置: 该位置就是 ui->volume按钮控件正上部分偏左一半
    QPoint volumeToolPoint = volumePointLeftTop - QPoint(volumeTool->width() / 2, volumeTool->height());

    // 微调窗口位置
    volumeToolPoint.setX(volumeToolPoint.x() + 15);
    volumeToolPoint.setY(volumeToolPoint.y() + 23);

    // 3.移动volumeTool
    volumeTool->move(volumeToolPoint);

    // 4. 将窗口显示出来
    volumeTool->show();
}


void QQMusic::on_addLocal_clicked()
{
    // 1.设置一个文件对话框
    QFileDialog filedialog(this);
    // 设置窗口标题
    filedialog.setWindowTitle("添加本地下载音乐");

    // 2. 创建一个打开格式的文件对话框(不设置,默认也是 open)
    filedialog.setAcceptMode(QFileDialog::AcceptOpen);

    // 3.设置对话框模式
    // 只能选择文件,并且一次打开多个已存在的文件
    filedialog.setFileMode(QFileDialog::ExistingFiles);


    //通过文件后缀来进行过滤文件
    // QFileDialog::setNameFilter()
    // 参数：filter 是一个字符串，定义了文件类型过滤器的规则。
    // 功能：设置对话框中显示的文件类型过下滤器，用户只能看到符合过滤器规则的文件。
    // filedialog.setNameFilter(QString("代码文件(*.h *.c *.hpp *.cpp)"));
    // filedialog.setNameFilter(QString("图像文件 (*.png *.jpg *.jpeg *.bmp)"));

    // 在过滤器字符串中，第一个过滤器会被默认选中。若要指定其他过滤器为默认，可结合 selectNameFilter()：
    // 设置多个过滤器
    // filedialog.setNameFilter(QString("图像文件 (*.png *.jpg *.jpeg *.bmp);;"
    //                                   "文档文件 (*.pdf *.docx *.xlsx);;"
    //                                   "所有文件 (*)" ));
    // 设置默认过滤器
    // filedialog.selectNameFilter("所有文件 (*)");  // 设置默认选中第三个过滤器
    // 缺点: 1.过滤器不生效; 2.用户无法看到所需文件 (推荐用void QFileDialog::setMimeTypeFilters(const QStringList &filters))

    // 4.设置对话框的MIME过滤器(选择MIME,没有选择上面的)
    QStringList mimeTypeFilters;
    mimeTypeFilters << "application/octet-stream";
    filedialog.setMimeTypeFilters(mimeTypeFilters);


    // 5.设置文件对话框的默认打开路径,设置 dir目录为当前工程文件所在路径
    QDir dir(QDir::currentPath());
    dir.cdUp();
    QString currentpath = dir.path() + "/ImitationQQMusicPlayer/musics";
    filedialog.setDirectory(currentpath);

    // 6.显示对话框,并接受返回值
    // 采用模态对话框,exec内部是死循环处理
    // int exec()  int --> enum QDialog::DialogCode{0, 1}; 1-->QDialog::Accepted:表示打开; 0-->QDialog::Rejected:表示取消
    if(filedialog.exec() == QDialog::Accepted)
    {
        // 切换到localPage界面,因为加载完音乐需要在本地页面显示
        ui->stackedWidget->setCurrentIndex(4);

        //获取对话框中,被选中的所有文件的url
        QList<QUrl> urls = filedialog.selectedUrls();

        // 拿到歌曲文件后，将歌曲文件交由musicList进行管理
        musicList.addMusicByUrl(urls);

        // 将音乐更新到local界面上
        ui->localPage->reFresh(musicList);

        // 将对应页面的音乐添加到 音乐播放列表里面
        ui->localPage->addMusicToplayList(musicList, playList);
    }
}

void QQMusic::onLrcwordClicked()
{
    lrcPage->show();
    lrcPageAnimal->start();
}

void QQMusic::updateLikeMusicAndPage(bool isLike, QString musicId)
{
    MusicList::iterator it = musicList.findMusicById(musicId);
    if(it == musicList.end())
        return;

    // 找到music 设置
    it->setIsLike(isLike);

    // 更新界面显示
    ui->likePage->reFresh(musicList);
    ui->localPage->reFresh(musicList);
    ui->recentPage->reFresh(musicList);
}

// 播放按钮(播放, 暂停)
void QQMusic::onPlayClicked()
{
    if(!playList->isEmpty())
    {
        if(QMediaPlayer::StoppedState == player->state())
        {
            // 若当前状态是停止, 则直接播放(一般是加载进来)
            player->play();
//            ui->play->setIcon(QIcon(":/images/play_on.png"));
        }
        else if(QMediaPlayer::PlayingState == player->state())
        {
            // 若当前状态是播放, 则直接暂停播放
            player->pause();
//            ui->play->setIcon(QIcon(":/images/play3.png"));
        }
        else if(QMediaPlayer::PausedState == player->state())
        {
            // 若当前状态是暂停播放, 则直接播放
            player->play();
//            ui->play->setIcon(QIcon(":/images/play_on.png"));
        }
        else
        {
            // 错误状态, 设置到最近一次的错误变量里面
            qDebug() << player->errorString();
        }
    }
}

// 播放器状态切换会触发信号
void QQMusic::onPlayerStatusChanged()
{
    if(QMediaPlayer::PlayingState == player->state())
    {
        ui->play->setIcon(QIcon(":/images/play_on.png"));
    }
    else // QMediaPlayer::PausedState
    {
        ui->play->setIcon(QIcon(":/images/play3.png"));
    }
}

void QQMusic::onPlayUpClicked()
{
    // 1.在单曲循环模式下,并且歌曲不唯一,点击下一首/上一首 可以向前或向后走
    // 2.任何模式下, 并且歌曲唯一, 点击下一首/上一首,重新播放
    // 3.在除了单曲循环模式下, 歌曲不唯一, 正常播放
    if(playList->playbackMode() == QMediaPlaylist::CurrentItemInLoop && playList->mediaCount() != 1)
    {
        // 实现效果: 在单曲循环模式下, 可以点击下一首/上一首(原来没有反应)
        int currentIndex = (playList->currentIndex() - 1) % playList->mediaCount();
        // 停止播放，重置索引，然后重新播放
        player->stop();
        playList->setCurrentIndex(currentIndex);
        player->play();
    }
    else if(playList->mediaCount() == 1)
    {
        // 实现效果: 点击下一首/上一首后可以重新播放(原来没有反应)
        int currentIndex = playList->currentIndex();
        // 停止播放，重置索引，然后重新播放
        player->stop();
        playList->setCurrentIndex(currentIndex);
        player->play();
        }
    else
    {
        playList->previous();
        // 实现效果: 在暂停的状态下, 点击下一首/上一首后,切换新歌并且播放歌曲(原来是不会播放歌曲的)
        if(player->state() == QMediaPlayer::PausedState)
        {
            player->play();
        }
    }
}

void QQMusic::onPlayDownClicked()
{
    // 同上
    if(playList->playbackMode() == QMediaPlaylist::CurrentItemInLoop && playList->mediaCount() != 1)
    {
        // 实现效果: 在单曲循环模式下, 可以点击下一首/上一首(原来没有反应)
        int currentIndex = (playList->currentIndex() + 1) % playList->mediaCount();
        // 停止播放，重置索引，然后重新播放
        player->stop();
        playList->setCurrentIndex(currentIndex);
        player->play();
    }
    else if(playList->mediaCount() == 1)
    {
        // 实现效果: 点击下一首/上一首后可以重新播放(原来没有反应)
        int currentIndex = playList->currentIndex();
        // 停止播放，重置索引，然后重新播放
        player->stop();
        playList->setCurrentIndex(currentIndex);
        player->play();
    }
    else
    {
        playList->next();
        // 实现效果: 在暂停的状态下, 点击下一首/上一首后,切换新歌并且播放歌曲(原来是不会播放歌曲的)
        if(player->state() == QMediaPlayer::PausedState)
        {
            player->play();
        }
    }
}

void QQMusic:: onPlaybackModeCliked()
{
    // 默认设置为列表循环
    if(QMediaPlaylist::Loop == playList->playbackMode())
    {
        // 若是播放模式是列表循环,则切换为随机循环
        ui->playMode->setToolTip("随机循环");// 提示词
        playList->setPlaybackMode(QMediaPlaylist::Random);
    }
    else if(QMediaPlaylist::Random == playList->playbackMode())
    {
        // 若是播放模式是随机循环,则切换为单曲循环
        ui->playMode->setToolTip("单曲循环");
        playList->setPlaybackMode((QMediaPlaylist::CurrentItemInLoop));
    }
    else if(QMediaPlaylist::CurrentItemInLoop == playList->playbackMode())
    {
        // 若是播放模式是单曲循环,则切换为列表循环
        ui->playMode->setToolTip("列表循环");
        playList->setPlaybackMode(QMediaPlaylist::Loop);
    }
    else
    {
        qDebug() << "播放模式错误";
    }
}

void QQMusic::onPlaybackModeChanged(QMediaPlaylist::PlaybackMode playbaclMode)
{
    if(QMediaPlaylist::Random == playbaclMode)
    {
        ui->playMode->setIcon(QIcon(":/images/shuffle_2.png"));
    }
    else if(QMediaPlaylist::CurrentItemInLoop == playbaclMode)
    {
        ui->playMode->setIcon(QIcon(":/images/single_play.png"));
    }
    else if(QMediaPlaylist::Loop == playbaclMode)
    {
        ui->playMode->setIcon(QIcon(":/images/order_play.png"));
    }
    else
    {
        qDebug() << "目前不支持该模式";
    }
}

//void QQMusic::playAll(PageType pageType)
//{
//    CommonPage* page;
//    switch(pageType)
//    {
//    case PageType::LIKE_PAGE:
//        page = ui->likePage;
//        break;
//    case PageType::LOCAL_PAGE:
//        page = ui->localPage;
//        break;
//    case PageType::HISTORY_PAGR:
//        page = ui->recentPage;
//        break;
//    default:
//        qDebug() << "暂时没有其他类型页面";
//        break;
//    }

//    // 通过类型得到要播放的页面以及音乐信息,从头播放
//    playAllOfCommonPage(page, 0);
//}
void QQMusic::playAll(CommonPage* page)
{
    // 通过类型得到要播放的页面以及音乐信息,从头播放
    playAllOfCommonPage(page, 0);
}

void QQMusic::playAllOfCommonPage(CommonPage* page, int index)
{
    currentPage = page;

    updateBtfromAnimal(); // 当前播放页面发生改动,btfrom也要改动

    // 将播放列表先清空，否则无法播放当前CommonPage页面的歌曲
    playList->clear();
    // 将当前页面歌曲添加到播放列表
    page->addMusicToplayList(musicList, playList);
    // 设置当前播放列表的索引
    playList->setCurrentIndex(index);
    // 播放
    player->play();
}

// 双击播放
void QQMusic::playMusicByIndex(CommonPage *page, int index)
{
    playAllOfCommonPage(page, index);
}

void QQMusic::onCurrentIndexChanged(int index)
{
    currentIndex = index; // 记录 正在播放的歌曲的索引

    // 由于CommonPage页面中的歌曲和正在播放的播放列表中的歌曲的先后次序是相同的
    // 知道歌曲在playlist中的索引之后，直接到CommonPage中获取
    // 注意：playlist中的歌曲就是根据CommonPage中的musicOfPage加载
    QString musicId = currentPage->getMusicIdByIndex(index);

    auto it = musicList.findMusicById(musicId);
    if(it != musicList.end())
    {
        it->setIsHistory(true);
    }

    // 将改变的musicList, 在recentPage页面重新生成
    ui->recentPage->reFresh(musicList);
}

// 处理静音操作
void QQMusic::setPlayerSilence(bool isMuted)
{
    player->setMuted(isMuted);
}

// 设置音乐音量
void QQMusic::setPlayerVolume(int volumeRatio)
{
    this->player->setVolume(volumeRatio);
}

// 音乐切换, 歌曲总时长也变化, 触发 durationChanged信号
void QQMusic::onDurationChanged(qint64 duration)
{
    totalTime  = duration;
    // duration 歌曲总时长 单位:毫秒
    // 分: duration/1000/60;
    // 秒: duration/1000%60
    ui->totalTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10, QChar('0'))
                                            .arg(duration/1000%60, 2, 10, QChar('0')));
}

// 音乐播放,时间不断变化, 触发positionChanged 信号
void QQMusic::onPositionChanged(qint64 position)
{
    // 更新当前播放时间
    ui->currentTime->setText(QString("%1:%2").arg(position/1000/60, 2, 10, QChar('0'))
                             .arg(position/1000%60, 2, 10, QChar('0')));
    // 进度条也要同步移动
    ui->progressBar->setStep(position / (float)totalTime);

    // 在歌词界面同步显示歌词
    if(currentIndex >= 0)
    {
        lrcPage->showLrcWordLine(position);
    }
}

void QQMusic::onMusicSliderChanged(float ration)
{
    // 1.计算滑动条对应的持续时间
    qint64 duration = (qint64)totalTime * ration;
    // 2.更新音乐当前时间点
    ui->currentTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10, QChar('0'))
                                             .arg(duration/1000%60, 2, 10, QChar('0')));
    // 3.将播放内容进行对应
    player->setPosition(duration);
}

void QQMusic::onMetaDataAvailableChanged(bool Available)
{
    (void)Available;
    // 歌曲名称、歌曲作者直接到Musci对象中获取
    // 此时需要知道媒体源在播放列表中的索引
    QString musicId = currentPage->getMusicIdByIndex(currentIndex);
    auto it = musicList.findMusicById(musicId);

    QString musicName("未知歌手");
    QString singer("未知歌手");
    if(it != musicList.end())
    {
        musicName = it->getMusicName();
        singer = it->getSingerName();
    }
    ui->musicName->setText(musicName);
    ui->musicSinger->setText(singer);

    // 获取封面图，通过元数据来获取
    QVariant coverimage = player->metaData("ThumbnailImage");
    if(coverimage.isValid())
    {
        QImage image = coverimage.value<QImage>();
        ui->musicCover->setPixmap(QPixmap::fromImage(image));
        currentPage->setMusicImage(QPixmap::fromImage(image));
    }
    else
    {
        qDebug() << "歌曲没有封面";
        // 设置为默认模式
        QString path = ":/images/rec/001.png";
        ui->musicCover->setPixmap(path);
        currentPage->setMusicImage(path);
    }
    ui->musicCover->setScaledContents(true); // 图片自动伸缩

    //  解析歌曲的lrc歌词
    if(it != musicList.end())
    {
        // 存在这首歌,通过歌曲拿到 歌词的路径
        QString lrcPath = it->getLrcPath();

        // 解析lrc文件
        lrcPage->parseLrcFile(lrcPath);
    }
}

void QQMusic::on_skin_clicked()
{
    // 换肤
    // 类似：给窗口更新背景颜色 或者 更换背景图片
    QMessageBox::information(this, "温馨提示", "换肤功能小哥哥正在紧急支持中...");
}

void QQMusic::on_min_clicked()
{
    showMinimized();
}
